﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
// Copyright (C) 2021 kingerrobot
// 版权所有。 
//
// 文件名：ExWarehousingAfterImpl
// 文件功能描述：出库线体任务生成
//
// 创建者：名字 (zzl)
// 时间：2021/12/30 9:30:32
//
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/
#endregion

using KingerRobot.MexicoSailunMDC.Dao;
using System.Threading.Tasks;

namespace KingerRobot.MexicoSailunMDC.SpiService;

public class ExWarehousingAfterImpl : IExWarehousingAfterService
{
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();
    private readonly static ITask _Task = new BTask();
    private readonly static IProdSku _ProdSku = new BProdSku();
    private readonly static IWcsLocSku _WcsLocSku = new BWcsLocSku();
    private readonly static IWcsAsrsNetOutPut _WcsAsrsNetOutPut = new BWcsAsrsNetOutPut();
    private readonly static IWcsAsrsCrnOutPut _WcsAsrsCrnOutPut = new BWcsAsrsCrnOutPut();
    private readonly static IWmsOutOrderSummary _WmsOutOrderSummary = new BWmsOutOrderSummary();
    private readonly static IWmsOutOrderMaster _WmsOutOrderMaster = new BWmsOutOrderMaster();
    private readonly static IProdProduct _ProdProduct = new BProdProduct();
    private readonly static IPositionService _PositionService = new PositionImpl();
    private readonly static IWms2MesService _Wms2MesService = new Wms2MesImpl();
    private readonly static IWcsOutputLog _WcsOutputLog = new BWcsOutputLog();
    private readonly static IRcsLocation _RcsLocation = new BRcsLocation();
    private readonly static IWcsEmsInput _WcsEmsInput = new BWcsEmsInput();
    private readonly static IRcsEquip _RcsEquip = new BRcsEquip();
    public long CreateTask(long locId, long taskId)
    {
        WriteLog($"出库放货位任务{taskId},,11", true);
        // 获取任务 判断当前位置是否有未执行
        var objId = _TaskCmd.GetOutPutExecutableTaskIdkByLocId(locId, taskId);
        if (objId != 0)
        {
            return objId;
        }
        WriteLog($"出库放货位任务{taskId},,22", true);
        // 查找主任务
        var task = _Task.GetTaskByTaskId(taskId);
        if (task == null)
        {
            return -2;
        }
        WriteLog($"出库放货位任务{taskId},,33", true);
        var targetLoc = task.TargetLoc.GetValueOrDefault();
        var skuId = task.SkuId.GetValueOrDefault();
        WriteLog($"出库放货位任务{taskId},,44", true);
        // 当前任务已创建
        var wcsLocSku = _WcsLocSku.GetWcsLocSkuNoTaskBySkuId(skuId, locId);
        if (wcsLocSku is null)
        {
            return -1;
        }
        WriteLog($"出库放货位任务{taskId},,55", true);

        // 获取堆垛机站台位
        var asrsCrnOutput = _WcsAsrsCrnOutPut.GetAsrsCrnOutputByOutPutLocId(locId);
        if (asrsCrnOutput == null)
        {
            return -3;
        }
        //var areaId = asrsCrnOutput.AreaId;
        WriteLog($"出库放货位任务{taskId},,66", true);
        var asrsNetOutput = _WcsAsrsNetOutPut.GetFirstAsrsNetOutputByTargetLoc(targetLoc);//.Where(t => t.AreaId == areaId).FirstOrDefault();
        if (asrsNetOutput?.TranLoc is not long tranLoc)
        {
            return -4;
        }
        WriteLog($"出库放货位任务{taskId},,77", true);
        //判断当前任务是否是单胎任务 如果是 则生成去A取料位的任务
        var group = task.TaskGroup;
        var groupCount = _Task.GetTasksByGroupNo(group ?? 0).Count();
        WriteLog($"出库放货位任务{taskId},,88", true);
        //单胎任务
        //if (groupCount < 2)
        //{
        //    var emsInput = asrsNetOutput?.TranLoc;
        //    var emsInputLoc = _RcsLocation.GetLocationById(emsInput ?? 0);
        //    //如果是单胎 并且此位置默认是b取货位 则强制改为a取货位
        //    if (emsInputLoc.GroupIndex == 1)
        //    {


        //        var newTranLoc = _RcsLocation.GetLoctionByLocCode(emsInputLoc.LocCode).Where(t => t.GroupIndex == 2).FirstOrDefault()?.Id ?? 0;
        //        //var emsInputInfo = _WcsEmsInput.GetEmsInputByLocId(newTranLoc);
        //        //if (emsInputInfo is not null)
        //        //{
        //        //    _RcsEquip.GetRcsEquipByDefaultLocId() 
        //        //}
        //        //对应设备可用的情况下再修改目的地
        //        var equipEnable = _RcsEquip.GetRcsEquipByDefaultLocId(newTranLoc).EquipEnable;
        //        if (equipEnable == 1)
        //        {
        //            tranLoc = newTranLoc;
        //        }
        //        //tranLoc = _RcsLocation.GetLoctionByLocCode(emsInputLoc.LocCode).Where(t => t.GroupIndex == 2).FirstOrDefault()?.Id ?? 0;
        //    }
        //}
        //判断默认ems是否被禁用 如果被禁用 则用另一个
        WriteLog($"出库放货位任务{taskId},,99,-{tranLoc}", true);
        var emsEquip = _RcsEquip.GetRcsEquipByDefaultLocId(tranLoc);
        if (emsEquip.EquipEnable == 0)
        {
            WriteLog($"出库放货位任务{taskId},,9912", true);
            var emsCode = emsEquip.EquipCode;
            var emsIndex = emsEquip.GroupIndex;
            var newemsEquip = _RcsEquip.GetRcsEquipListByCode(emsCode).Where(t => t.GroupIndex != emsIndex).FirstOrDefault();
            tranLoc = newemsEquip.EmsDefaultLoc ?? 0;
        }
        WriteLog($"出库放货位任务{taskId},tranLoc{tranLoc},100", true);


        // 获取旋转扫描
        //var netCuring = _WcsNetInCuring.GetWcsNetinCuringByTranLoc(tranLoc);

        //var scannerLoc = netCuring?.ScannerLoc ?? 0; // 扫描仪位置

        // 获取订单
        var summaryId = task.SummaryId.GetValueOrDefault();
        var summary = _WmsOutOrderSummary.GetOutOrderSummaryById(summaryId);
        WriteLog($"出库放货位任务{taskId},,111", true);
        // 创建
        var cmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = taskId,
            TaskNo = task.TaskNo,
            TaskType = (int)EnumTaskType.Transportation,

            StartLoc = locId,
            CurrentLoc = locId,
            TargetLoc = tranLoc,

            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = (int)EnumTaskType.Transportation,

            SpinAngle = summary?.RotateAngle ?? 0,
            //IsSpray = isSpray,
        });
        WriteLog($"出库放货位任务{taskId},,112", true);
        // 修改任务喷涂
        //_Task.UpdateTaskSpray(taskId, isSpray);

        // 修改位置赋值任务
        _WcsLocSku.UpdateWcsLocSkuTask(skuId, taskId);

        //// 位置绑定流水号
        //_PositionService.UpdateRcsLocation(locId, task.TaskNo.GetValueOrDefault());
        return taskId;
    }

    public BizTaskBean CreateTaskV2(long locId, long taskId)
    {

        var result = new BizTaskBean();
        //_WcsOutputLog.CreateOrUpdateWcsOutputLog(taskId, 0, (int)EnumOutputLogPlan.LineCreateStart);
        var outTaskId = CreateTask(locId, taskId);
        if (outTaskId > 0)
        {
            result = _Task.GetOutTaskByTaskId(taskId);
            // _WcsOutputLog.CreateOrUpdateWcsOutputLog(taskId, 0, (int)EnumOutputLogPlan.LineCreateEnd);
            return result;
        }

        return result;
    }

    /// <summary>
    /// 创建出库线体任务
    /// </summary>
    /// <param name="locId"></param>
    /// <param name="taskId"></param>
    /// <returns></returns>
    public long CreateLocOutTask(long locId, long taskId)
    {
        // _WcsOutputLog.CreateOrUpdateWcsOutputLog(taskId, 0, (int)EnumOutputLogPlan.LineCreateStart);
        // 查找主任务
        var task = _Task.GetTaskByTaskId(taskId);
        if (task == null)
        {
            return -2;
        }
        var targetLoc = task.TargetLoc.GetValueOrDefault();
        var skuId = task.SkuId.GetValueOrDefault();

        var taskCmd = _TaskCmd.GetTaskCmdByTaskId(taskId);
        if (taskCmd is not null
            && taskCmd.StartLoc == locId
            && taskCmd.CmdType == (int)EnumTaskType.Transportation
            && taskCmd.CmdStatus == (int)EnumTaskCmdStatus.Executable)
        {
            return taskCmd.TaskId.GetValueOrDefault();
        }


        // 当前任务已创建
        var wcsLocSku = _WcsLocSku.GetWcsLocSkuNoTaskBySkuId(skuId, locId);
        if (wcsLocSku is null)
        {
            return -1;
        }

        // 创建
        var cmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskId = taskId,
            TaskNo = task.TaskNo,
            TaskType = (int)EnumTaskType.Transportation,

            StartLoc = locId,
            CurrentLoc = locId,
            TargetLoc = targetLoc,

            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = (int)EnumTaskType.Transportation,

            IsSpray = 0,
        });
        // 修改位置赋值任务
        _WcsLocSku.UpdateWcsLocSkuTask(skuId, taskId);
        //_WcsOutputLog.CreateOrUpdateWcsOutputLog(taskId, 0, (int)EnumOutputLogPlan.LineCreateEnd);
        //// 位置绑定流水号
        //_PositionService.UpdateRcsLocation(locId, task.TaskNo.GetValueOrDefault());
        return taskId;
    }
    public int ExecuteTask(int taskNo, long locId)
    {
        var taskCmd = _TaskCmd.GetExecutableTaskCmdByTaskNo(taskNo);
        if (taskCmd?.TaskId is not long taskId)
        {
            return 0;
        }

        // 修改命令状态
        var num = _TaskCmd.UpdateTaskCmdStatus(locId, taskId, (int)EnumTaskCmdStatus.Executed);
        //判断是异常出库任务就直接结束线体指令
        var task = _Task.GetTaskByTaskNo(taskNo);

        // 清空绑定为
        // var skuId = task.SkuId.GetValueOrDefault();
        // _WcsLocSku.DeleteWcsLocSkuBySku(skuId);

        // 库位出库进异常口任务直接删除
        var master = _WmsOutOrderMaster.GetOutOrderMasterById(task.MasterId.GetValueOrDefault());
        if (master.OrderType == (int)EnumCodeOutOrderType.WarehouseLocation)
        {
            //FinishTask(taskNo, locId);

            _WmsOutOrderSummary.BakAndDeleteOutOrderSummary(task.SummaryId.GetValueOrDefault());

            var summaryCount = _WmsOutOrderSummary.GetOutOrderSummaryByMasterId(master.Id.GetValueOrDefault()).Count();
            if (summaryCount == 0)
            {
                _WmsOutOrderMaster.BakOutOderMaster(master);
                _WmsOutOrderMaster.DeleteOutOderMaster(master.Id);
            }

        }
        return num;
    }
    public int FinishTask(int taskNo, long locId)
    {
        var taskCmd = _TaskCmd.GetExecutedTaskCmdByTaskNo(taskNo);
        if (taskCmd?.TaskId is not long taskId)
        {
            return 0;
        }
        var targetLoc = taskCmd.TargetLoc.GetValueOrDefault();

        // 获取 skuID
        var task = _Task.GetTaskByTaskNo(taskNo);
        if (task?.SkuId is not long skuId)
        {
            return -1;
        }

        // 修改状态
        _TaskCmd.UpdateTaskCmdStatus(locId, taskId, (int)EnumTaskCmdStatus.Finish);
        // 备份删除
        _TaskCmd.BakAndDeleteCmd(taskId);
        // 库位出库进异常口任务直接删除
        var master = _WmsOutOrderMaster.GetOutOrderMasterById(task.MasterId.GetValueOrDefault());
        if (master.OrderType == (int)EnumCodeOutOrderType.WarehouseLocation)
        {
            _Task.BakAndDeleteTask(taskId);
            // 同步MES
            //SyncMes(productCode, taskId);
        }
        else
        {
            // 重置货位定位
            _WcsLocSku.SetWcsLocSku(targetLoc, skuId);
        }
        return 1;
    }
    public int EmsInputFinishTask(string productCode, long locId, int taskNo, long taskId)
    {
        // 修改状态
        var num1 = _TaskCmd.UpdateTaskCmdStatus(locId, taskId, (int)EnumTaskCmdStatus.Finish);
        if (num1 > 0)
        {
            WriteLog($"返回{num1},流水号{taskNo},条码{productCode}任务id{taskId}ems取料位修改成功", true);
        }
        else
        {
            WriteLog($"返回{num1},流水号{taskNo},条码{productCode}任务id{taskId}ems取料位修改失败", true);
            //return 0;
        }
        WriteLog($"返回{num1},流水号{taskNo},开始删除指令", true);
        _TaskCmd.BakAndDeleteCmd(taskId);
        WriteLog($"返回{num1},流水号{taskNo},完成删除指令", true);
        // 修改货位TaskId
        var num = _PositionService.UpdateEmsRcsLocationIsProductCode(locId, taskNo);
        WriteLog($"返回{num},流水号{taskNo},完成绑定位置", true);
        return num;
    }
    public int EmsInputEMSAbnormalTask(long locId)
    {

        //var abnormalSku = _ProdSku.GetProdSkuListBySkuCode("EMSABNORMAL")?.FirstOrDefault();

        var abnormalSku = _ProdSku.CreateProdSku(new ProdSkuBean()
        {
            SkuCode = "EMSABNORMAL",
            MaterialId = 588276728778982273,
            ProductBatch = "",
            MdTime = DateTime.Now,
        });

        // 清空已绑定 TaskId 货位
        // _RcsLocation.ClearLocationHasTaskByTaskId(task.Id.GetValueOrDefault());
        WriteLog($"位置{locId}开始绑定有胎无信息1");
        var result = _RcsLocation.UpdateLocationHasTask(locId,
            1,
            abnormalSku?.Id ?? 0
            );
        WriteLog($"位置{locId}开始绑定有胎无信息2");
        // 绑定位置
        var num = _WcsLocSku.SetWcsLocSku(locId, abnormalSku?.Id ?? 0);
        WriteLog($"位置{locId}开始绑定有胎无信息3");
        return num;
    }

    public int CreateOrUpdateWcsOutputLog(int taskNo, int logType, string remark = "")
    {
        return 1;
        //var taskId = _Task.GetTaskByTaskNo(taskNo)?.Id ?? 0;
        //return  _WcsOutputLog.CreateOrUpdateWcsOutputLog(taskId, taskNo, logType, remark);
    }


    /// <summary>
    /// 同步MES
    /// </summary>
    /// <param name="task"></param>
    private void SyncMes(string productCode, long taskId)
    {
        //推送出库订单状态(WMS->MES)
        var task = _Task.GetTaskByTaskId(taskId);
        List<PushOutOrderStatusParam> pushOutOrderStatusParams = new List<PushOutOrderStatusParam>();
        pushOutOrderStatusParams.Add(new PushOutOrderStatusParam
        {
            OrderDetailId = task.SummaryId?.ToString(),
            OrderStatus = (int)EnumPushOutOrderStatus.LineTransportationFinish,
            TireBarcode = productCode
        });
        _Wms2MesService.PushOutOrderStatus(pushOutOrderStatusParams);
    }

    public int UpdateCmdStatusByTaskId(long? taskId, int status, int type)
    {
        return _TaskCmd.UpdateCmdStatusByTaskIdAndType(taskId ?? 0, status, type);
    }


    public int CacheBindingLocTaskNo(long locId, int taskNo)
    {
        var task = _Task.GetTaskByTaskNo(taskNo);
        if (task == null)
        {
            return 0;
        }

        var skuId = task.SkuId.GetValueOrDefault();

        // 修改位置赋值任务
        _WcsLocSku.SetWcsLocSku(locId, skuId);

        return 1;
    }
    public object VerificationTaskAndBarCode(string barCode, int taskNo)
    {
        var task = _Task.GetTaskByTaskNo(taskNo);
        if (task == null)
        {
            return 0;
        }

        var sku = _ProdSku.GetProdSkuBySkuCode(barCode);
        if (sku == null)
        {
            return -1;
        }
        //
        if (task.Id == sku.Id)
        {
            var taskCmd = _TaskCmd.GetTaskCmdByTaskNo(taskNo);
            if (taskCmd == null)
            {
                return -2;
            }
            return taskCmd;
        }
        else
        {
            return -3;
        }

    }
}